package com.copractice.beans.create;

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.copractice.beans.BaseBean;
import com.copractice.beans.common.Constants;
import com.copractice.beans.common.MessagesUtil;
import com.copractice.bl.BLFactory;
import com.copractice.bl.question.QuestionBL;
import com.copractice.bl.question.QuestionToSave;
import com.copractice.bl.tags.TagsBL;
import com.copractice.data.entity.tag.Tag;

public class CreateBean extends BaseBean {
    
    private static final Logger LOG = LoggerFactory.getLogger(CreateBean.class);
    
    private static final String SELECT_QUESTION_CATEGORY = "create.select_question_category";
    private static final String DEFAULT_HINT_MESSAGE = "create.enter_default_hint";    
    private static final String QUESTION_TEXT = "create.question_text";
    private static final String NEW_CATEGORY = "create.new_category";    
    
    private String questionText; //contains questions text
    
    private String rightAnswer;
    
    private String incorrectAnswer1;
    private String incorrectAnswer2;
    private String incorrectAnswer3;
    
    private String defaultHint;
    private String newCategory;
    private Long selectedCategoryId = 0L;
    private Long difficulty = 0L; 
    private Long star;
    
    public CreateBean() {
        defaultHint = MessagesUtil.getBundleMessage(Constants.MESSAGE_BUNDLE, DEFAULT_HINT_MESSAGE);
        questionText = MessagesUtil.getBundleMessage(Constants.MESSAGE_BUNDLE, QUESTION_TEXT);
        newCategory = MessagesUtil.getBundleMessage(Constants.MESSAGE_BUNDLE, NEW_CATEGORY); 
    }
    
    /**
     * Returns list of <code>SelectItem</code> of available categories.
     * @return
     */
    public List<SelectItem> getCategories() {
        TagsBL tagsBL = BLFactory.getInstance(TagsBL.class);
        
        List<Tag> tags = tagsBL.getAllTags();
        
        List<SelectItem> items = new ArrayList<SelectItem>();
        items.add(new SelectItem(new Long(0), 
                                 MessagesUtil.getBundleMessage(Constants.MESSAGE_BUNDLE, SELECT_QUESTION_CATEGORY)));
        
        if (tags != null) {
            for(Tag tag : tags) {
                items.add(new SelectItem(tag.getId(), tag.getName()));
            }
        }
        
        if (LOG.isDebugEnabled()) {
            LOG.debug("Available categories: {}", items);
        }
         
        return items;
    }     
    
    /**
     * Creates new question and saves in database.
     */
    public String createNewQuestion() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Create New question");
        }
        
        QuestionBL questionBL = BLFactory.getInstance(QuestionBL.class);
        
        QuestionToSave question = new QuestionToSave(questionText);
        question.addDifficulty(getDifficulty()).addHint(getDefaultHint())
                .addAnswers(getIncorrectAnswers(), rightAnswer);
        
        if(selectedCategoryId == 0) {
            question.addCategoryName(newCategory);
        } else {
            question.setCategoryId(selectedCategoryId);
        }
        
        //TODO process the result of the question insertion
        boolean result = questionBL.addQuestion(question, (Long) getSessionAttribute(Constants.USER_ID));
        if (result && LOG.isDebugEnabled()) {
            LOG.debug("Question was created");
        }
        
        return "created";
    }
    
    /**
     * Returns incorrect answers for new question.
     * 
     * @return list of incorrect answers
     */
    private List<String> getIncorrectAnswers() {
        List<String> answers = new ArrayList<String>();
        answers.add(incorrectAnswer1);
        answers.add(incorrectAnswer2);
        answers.add(incorrectAnswer3);
        return answers;
    }    
    
    public void setDifficultyValue() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Sets difficulty level: " + getStar());
        }
        setDifficulty(getStar());
    }
    
    public Long getDifficulty() {
        return difficulty;
    }

    public void setDifficulty(Long difficulty) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Set difficulty level to: " + difficulty);
        }
        this.difficulty = difficulty;
    }    

    public String getQuestionText() {
        return questionText;
    }

    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    public String getRightAnswer() {
        return rightAnswer;
    }

    public void setRightAnswer(String rightAnswer) {
        this.rightAnswer = rightAnswer;
    }

    public String getIncorrectAnswer1() {
        return incorrectAnswer1;
    }

    public void setIncorrectAnswer1(String incorrectAnswer1) {
        this.incorrectAnswer1 = incorrectAnswer1;
    }

    public String getIncorrectAnswer2() {
        return incorrectAnswer2;
    }

    public void setIncorrectAnswer2(String incorrectAnswer2) {
        this.incorrectAnswer2 = incorrectAnswer2;
    }

    public String getIncorrectAnswer3() {
        return incorrectAnswer3;
    }

    public void setIncorrectAnswer3(String incorrectAnswer3) {
        this.incorrectAnswer3 = incorrectAnswer3;
    }

    public Long getSelectedCategoryId() {
        return selectedCategoryId;
    }

    public void setSelectedCategoryId(Long selectedCategoryId) {
        this.selectedCategoryId = selectedCategoryId;
    }

    public String getNewCategory() {
        return newCategory;
    }

    public void setNewCategory(String newCategory) {
        this.newCategory = newCategory;
    }

    public String getDefaultHint() {
        return defaultHint;
    }

    public void setDefaultHint(String defaultHint) {
        this.defaultHint = defaultHint;
    }
    
    public Long getStar() {
        return star;
    }

    public void setStar(Long star) {
        this.star = star;
    }    
    
    public String getStar1() {
        return getStarValue(1);
    }

    public String getStar2() {
        return getStarValue(2);
    }
    
    public String getStar3() {
        return getStarValue(3);
    }
    
    public String getStar4() {
        return getStarValue(4);
    }

    public String getStar5() {
        return getStarValue(5);
    }
    
    private String getStarValue(int val) {
        if (getStar() == null || val > getDifficulty()) {
            return Constants.STAR_EMPTY;
        } else {
            return Constants.STAR;
        }
    }    

}
